import java.io.IOException;
import java.net.Socket;
import java.util.Vector;


public class ControlSession {

	private ConnectedDevice controller;
	private ConnectedDevice vehicle;
	
	private Vector<String> pubName;
	
	Thread controllerThread, vehicleThread, cThrJoin;
	
	//TODO make this more generic (make a two-way buffer/interface to a buffer generic maybe)
	private ConnectedDeviceBuffer cntrlToVehBuf_cmd, vehToCntrlBuf_vid;
	
	public ControlSession(Socket controllerConn, Socket vehConn) {
		this.cntrlToVehBuf_cmd = new ConnectedDeviceBuffer();
		this.vehToCntrlBuf_vid = new ConnectedDeviceBuffer();
		
		try {
			this.controller = new ConnectedDevice(controllerConn, cntrlToVehBuf_cmd, vehToCntrlBuf_vid);
			this.vehicle = new ConnectedDevice(vehConn, cntrlToVehBuf_cmd, vehToCntrlBuf_vid);
		} catch (IOException e) { e.printStackTrace(); }
		controller.setDeviceTypeForTest(ConnectedDevice.device_type.CONTROLLER);
		vehicle.setDeviceTypeForTest(ConnectedDevice.device_type.VEHICLE);
		controllerThread = new Thread(controller);
		vehicleThread = new Thread(vehicle);
		
		controllerThread.start();
		vehicleThread.start();
		
		try {
			System.out.println("Trying to join the controller's thread");
			//controllerThread.join();
			cThrJoin = new Thread() {
				public void run() {
					try {
						controllerThread.join();
						System.out.println("Successfully joined the controller's thread");
						System.out.println("Requesting that the vehicle's thread stop");
						vehicle.requestStop();
						//write another message to the buffer so that the vehicle's thread won't deadlock us
						byte[] stopMsg = {0, 0, 0, 0, 0, 0, 0, 0};
						cntrlToVehBuf_cmd.produce(stopMsg);
						
						System.out.println("Trying to join the vehicle's thread");
						vehicleThread.join();
						System.out.println("Successfully joined the vehicle's thread");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			};
			cThrJoin.start();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		this.pubName = new Vector();
		this.pubName.add(controllerConn.getRemoteSocketAddress().toString());
		this.pubName.add(vehConn.getRemoteSocketAddress().toString());
	}
	
	public Vector<String> getPubName() {
		return this.pubName;
	}
	
	public boolean isStopped() {
		if( !((this.vehicleThread.isAlive()) || (this.controllerThread.isAlive())) ) {
			try {
				cThrJoin.join();
				return true;
			} catch (InterruptedException e) { e.printStackTrace(); }
		}
		return false;
	}
}
